package com.own.business.log.operation.persistence.business.hook;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.own.business.log.operation.persistence.business.service.LogOperationElasticService;
import com.own.business.log.operation.persistence.entity.po.LogOperationElasticPo;
import com.own.component.log.operation.core.PersistenceLogOperationHook;
import com.own.component.log.operation.entity.LogOperationEntity;
import com.own.component.util.time.ZonedDateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.UUID;

/**
 * DefaultAfterLogOperationHook
 *
 * @author chenxueli
 * @date 2023-07-31 21:34:00
 */
@Slf4j
@Component("persistenceLogOperationHook")
public class DefaultAfterLogOperationHook implements PersistenceLogOperationHook {

    private static final String TO_LONG;

    static {
        var object = new JSONObject();
        object.put("data", "响应数据过长，请优化");
        TO_LONG = object.toJSONString();
    }

    @Resource
    private LogOperationElasticService logOperationElasticService;

    /**
     * 获取对应的日志操作接口
     *
     * @param entity 对象信息
     */
    @Override
    public void run(LogOperationEntity entity) {
        var po = new LogOperationElasticPo();
        if (entity.getLoginUser() != null) {
            po.setFkUserId(entity.getLoginUser().userId());
            po.setUserName(entity.getLoginUser().userName());
            po.setToken(entity.getLoginUser().token());
        }
        po.setId(UUID.randomUUID().toString());
        po.setGmtCreate(ZonedDateTime.now());
        po.setLevel(entity.getLevel());
        po.setCode(entity.getCode());
        po.setIp(entity.getIp());
        po.setClient(entity.getClient());
        po.setMessage(entity.getMessage());
        po.setMethodName(entity.getMethodName());
        po.setModuleName(entity.getModuleName());
        po.setOperationName(entity.getOperationName());
        po.setExtra(entity.getExtra());
        po.setStatus(entity.getStatus());
        po.setTraceId(entity.getTraceId());
        po.setHeaderParams(entity.getHeaders());
        po.setRequestUrl(entity.getRequestUrl());
        po.setRequestMethod(entity.getRequestMethod());
        if (entity.getRequest() != null) {
            po.setRequestTime(ZonedDateTimeUtil.of(entity.getRequest().getTime()));
            po.setRequestParams(entity.getRequest().getParams());
        }
        if (entity.getResponse() != null) {
            po.setResponseTime(ZonedDateTimeUtil.of(entity.getResponse().getTime()));
            var responseParams = JSON.toJSONString(entity.getResponse().getParams());
            po.setResponseParams(responseParams.length() > 40000 ? TO_LONG : responseParams);
        }
        if (po.getRequestTime() != null && po.getResponseTime() != null) {
            po.setHandleTime(Duration.between(po.getRequestTime(), po.getResponseTime()).toMillis());
        }
        po.setService(entity.getService());
        logOperationElasticService.add(po);
    }

}
